package com.fh.config.security;

import cn.hutool.core.util.ObjectUtil;
import com.fh.bean.User;
import com.fh.service.UserRepositoryService;
import com.fh.utils.anomaly.SpringSecurityException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;

/**
 * 登录的时候判断账户密码是否正确
 */
@Slf4j
@Configuration
public class CustomAuthenticationProviderConfig implements AuthenticationProvider {

    @Autowired
    private UserRepositoryService iSysUserService;


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String username = authentication.getName();
        String presentedPassword = String.valueOf(authentication.getCredentials());
        // 根据用户名获取用户信息
        User sysUser = this.iSysUserService.findByUsername(username);
        if(ObjectUtil.isNull(sysUser)){
            throw new RuntimeException("用户名不存在");
        }

        if(sysUser.isAccount(sysUser.getAccountExpired())){
            throw new AuthenticationServiceException("账户已过期");
        }
        if(sysUser.isAccount(sysUser.getAccountLocked())){
            throw new SpringSecurityException("用户已禁用");
        }


        if(!StringUtils.hasText(presentedPassword)){
            throw new SecurityException("密码不能为空");
        }

        if(!passwordEncoder.matches(presentedPassword,sysUser.getPassword())){
            throw new SpringSecurityException("密码错误");
        }


        UserDetails userDeatils = org.springframework.security.core.userdetails.User.builder()
                .username(sysUser.getUsername())
                .password(sysUser.getPassword())
                .authorities(new SimpleGrantedAuthority(sysUser.getRole()))
                .disabled(sysUser.isAccount(sysUser.getAccountLocked()))
                .accountExpired(sysUser.isAccount(sysUser.getAccountExpired()))
                .build();
        // 自定义的加密规则，用户名、输的密码和数据库保存的盐值进行加密

        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(userDeatils, authentication.getCredentials(), userDeatils.getAuthorities());
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}